<?php

/**
 * 微信管理逻辑处理层
 * @author Reer
 * @email  reer_shu_re@163.com
 */

namespace app\common\manage;


use app\common\bean\GlobalBean;
use app\common\bean\ListMap;
use app\common\bean\StoreBean;
use app\common\bean\UserBean;
use app\common\enum\StoreStatusEnum;
use app\common\enum\UserStatusEnum;
use app\common\exception\MyException;
use app\common\model\StoreModel;
use app\common\model\UserModel;
use app\common\utils\AppletWechatUtil;
use app\common\utils\PublicWechatUtil;
use app\common\utils\RASUtil;
use app\common\utils\TimeUtil;
use Exception;

class WechatManage
{
    protected static $_self = null;

    static function getInstance() {
        if (empty(self::$_self)) {
            self::$_self = new WechatManage();
        }
        return self::$_self;
    }

    /**
     * 初始化验证是否登录
     * @param string $code     小程序login接口返回的code
     * @param int    $store_id //小程序太阳码参数值商家id
     * @return int 200已授权 501未授权
     * @throws Exception
     */
    public function login($code, $store_id) {
        $resultMap = AppletWechatUtil::getInstance()->oauth($code);
        $openid = $resultMap->getParameter('openid');
        if (!$user = UserModel::getInstance()->selectData([UserBean::$appletOpenId => $openid], false, '', 'user_vip')) {
            $data[UserBean::$appletOpenId] = $openid;
            $data[UserBean::$storeId] = $store_id;
            $data[UserBean::$createdAt] = date('Y-m-d H:i:s');
            $uid = UserModel::getInstance()->addDataGetInsertId($data);
            $user['token'] = RASUtil::getInstance()->encrypt(json_encode(array(UserBean::$appletOpenId => $openid, UserBean::$id => $uid, GlobalBean::$expireTime => time() + 60 * 60 * 24 * 2)));
            $user['code'] = 501;
            return $user;
        }
        $user['code'] = $user[UserBean::$avatarUrl] ? 200 : 501;
        $user['token'] = RASUtil::getInstance()->encrypt(json_encode(array(UserBean::$appletOpenId => $openid, UserBean::$id => $user[UserBean::$id], GlobalBean::$expireTime => time() + 60 * 60 * 24 * 2)));
        return $user;

    }

    /** 微信公众号网页授权
     * @param $redirectUrl
     * @throws Exception
     */
    public function publicWechatAuth($redirectUrl) {
        $redirectUrl ?: MyException::throwMyException("跳转url不可为空");
        PublicWechatUtil::getInstance()->oauth($redirectUrl);
    }

    /** 微信小程序code值获取openid
     * @param $code
     * @param $iv
     * @param $encryptedData
     * @return UserBean
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     * @throws Exception
     */
    public function userAuthApplet(ListMap $listMap) {
        //$code ?: MyException::throwMyException("code值不能为空");
        //$resultMap = AppletWechatUtil::getInstance()->oauth($code);
        $resultMap = new ListMap();
        $resultMap->setParameter("iv", $listMap->getParameter('iv'));
        $resultMap->setParameter("encryptedData", $listMap->getParameter('encryptedData'));
        $resultMap->setParameter("session_key", $listMap->getParameter('session_key'));
        if (!$resultMap->getParameter('session_key'))
            MyException::throwMyException("获取不到session_key");
        $resultMap = AppletWechatUtil::getInstance()->decryptedData($resultMap);
        $userBean = new UserBean();
        $userBean->setAppletOpenId($resultMap->getParameter("openId"));
        $userBean->setNickname($resultMap->getParameter("nickName"));
        $userBean->setGender($resultMap->getParameter("gender"));
        $userBean->setCity($resultMap->getParameter("city"));
        $userBean->setProvince($resultMap->getParameter("province"));
        $userBean->setCountry($resultMap->getParameter("country"));
        $userBean->setAvatarUrl($resultMap->getParameter("avatarUrl"));
        $userBean->setUnionId($resultMap->getParameter("unionId"));
        $userBean->setCreatedAt(TimeUtil::getInstance()->getTimeNow());
        if($resultMap->getParameter("openId")=='ooWWa5fMZzRwlkxicDT9jWaEUWHY'){
            $stid = 3;
        }else{
            if($listMap->getParameter('stid')){
                $stid = $listMap->getParameter('stid');
            }else{
                $store = $this->getLatelyStore($listMap);
                $stid = $store[StoreBean::$id];
            }
        }
        $userBean->setStoreId($stid);

        if ($userBean->getUnionId()) {
            $result = UserModel::getInstance()->selectData(array(UserBean::$unionId => $userBean->getUnionId()));
            if ($result == false)
                $result = UserModel::getInstance()->selectData(array(UserBean::$appletOpenId => $userBean->getAppletOpenId()));
        } else {
            $result = UserModel::getInstance()->selectData(array(UserBean::$appletOpenId => $userBean->getAppletOpenId()));
        }
        if ($result === false) {//第一次授权
            $userBean->setStatus(UserStatusEnum::NORMAL);
            $userId = UserManage::getInstance()->add($userBean);
            $userBean->setId($userId);
        } else {
            //更新用户信息
            $userBean->setId($result[UserBean::$id]);
            UserManage::getInstance()->edit($userBean);
            $result = UserModel::getInstance()->selectData([UserBean::$id => $userBean->getId()]);
            $userBean->setData($result);
            $userBean->getStatus() == UserStatusEnum::NORMAL ?: MyException::throwMyException("用户被禁用");
        }

        $token = RASUtil::getInstance()->encrypt(json_encode(array(UserBean::$appletOpenId => $userBean->getAppletOpenId(), UserBean::$id => $userBean->getId(), GlobalBean::$expireTime => time() + 60 * 60 * 24 * 2)));
        $token ?: MyException::throwMyException("加密令牌出错");
        $returnUserBean = new UserBean();
        $returnUserBean->setData($userBean->getData());

        $returnUserBean->setParameter('store', $this->getStore($userBean, $listMap));
        $returnUserBean->removeField(UserBean::$unionId);
        $returnUserBean->removeField(UserBean::$appletOpenId);
        $returnUserBean->removeField(UserBean::$createdAt);
        $returnUserBean->setParameter(GlobalBean::$token, $token);
        return $returnUserBean;
    }
    private function getStore(UserBean $userBean, $listMap){
        $res = false;
        if($store = StoreModel::getInstance()->selectData([StoreBean::$id=>$userBean->getStoreId(), StoreBean::$status=>StoreStatusEnum::SUCCESS])){
            $res = true;
        }
        if(!$res){
            $store = $this->getLatelyStore($listMap);
            UserModel::getInstance()->updateColumn(UserBean::$id, $userBean->getId(),UserBean::$storeId,$store[StoreBean::$id]);
        }
        return $store;
    }
    private function getLatelyStore($listMap){
        $contact_addr_lat = $listMap->getParameter('contact_addr_lat');
        $contact_addr_lng = $listMap->getParameter('contact_addr_lng');
        $disField = getDisField($contact_addr_lat, $contact_addr_lng, StoreBean::$contactAddrLat, StoreBean::$contactAddrLng);
        $field = [$disField, StoreBean::$companyName, StoreBean::$id, StoreBean::$contactAddr];
        return StoreModel::getInstance()->selectData([StoreBean::$status=>StoreStatusEnum::SUCCESS], false, 'distance ACS', '', $field);
    }
    /** 微信小程序code值获取openid
     * @param $code
     * @param $iv
     * @param $encryptedData
     * @return \app\common\bean\ListMap
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     */
    public function mobilePhone($code, $iv, $encryptedData) {
        $code ?: MyException::throwMyException("code值不能为空");
        $resultMap = AppletWechatUtil::getInstance()->oauth($code);
        $resultMap->setParameter("iv", $iv);
        $resultMap->setParameter("encryptedData", $encryptedData);
        if (!$resultMap->getParameter('session_key'))
            MyException::throwMyException("获取不到session_key");
        $resultMap = AppletWechatUtil::getInstance()->decryptedData($resultMap);
        return $resultMap;
    }

    /** 微信公众号授权回调解析用户授权信息
     * @return UserBean
     */
    public function publicWechatCallback() {
        try {
            $user = PublicWechatUtil::getInstance()->getOauthInfo();
            $userBean = new UserBean();
            $userBean->setPublicOpenId($user->getId());
            $userBean->setAvatarUrl($user->getAvatar());
            $userBean->setNickname($user->getNickname());
            $userBean->setCity($user->getOriginal()['city']);
            $userBean->setProvince($user->getProviderName());
            $userBean->setCountry($user->getOriginal()['country']);
            $userBean->setGender($user->getOriginal()['sex']);
            $result = UserModel::getInstance()->selectData(array(UserBean::$publicOpenId => $userBean->getPublicOpenId()));
            if ($result === false) {//第一次授权
                $userId = UserManage::getInstance()->add($userBean);
                $userBean->setId($userId);
            } else {//授权有用户信息
                $userBean->setId($result[UserBean::$id]);
                $userBean->setStatus($result[UserBean::$status]);
                UserManage::getInstance()->edit($userBean);
                $userBean->getStatus() == UserStatusEnum::NORMAL ?: MyException::throwMyException("用户被禁用");
            }
            $token = RASUtil::getInstance()->encrypt(json_encode(array(UserBean::$publicOpenId => $userBean->getPublicOpenId(), UserBean::$id => $userBean->getId(), GlobalBean::$expireTime => time() + 60 * 60 * 24 * 2)));
            $token ?: MyException::throwMyException("加密令牌出错");
            $returnUserBean = new UserBean();
            $returnUserBean->setId($userBean->getId());
            $returnUserBean->setNickname($userBean->getNickname());
            $returnUserBean->setAvatarUrl($userBean->getAvatarUrl());
            $returnUserBean->setParameter(GlobalBean::$token, $token);
            return $returnUserBean;
        } catch (Exception $exception) {
            echo "授权失败，跳转前端错误页".$exception->getMessage();
            exit();
        }
    }


    /**
     * 小程序通过code值获取用户信息
     * @throws Exception
     */
    public function getUserByCode($code) {
        $code ?: MyException::throwMyException("code值不能为空");
        $resultMap = AppletWechatUtil::getInstance()->oauth($code);
        //$user = UserModel::getInstance()->selectData([UserBean::$appletOpenId => $resultMap->getParameter("openid")], false, '', '');
        //if ($user) {
        //    $token = RASUtil::getInstance()->encrypt(json_encode(array(UserBean::$appletOpenId => $user[UserBean::$appletOpenId], UserBean::$id => $user[UserBean::$id], GlobalBean::$expireTime => time() + 60 * 60 * 24 * 2)));
        //    $token ?: MyException::throwMyException("加密令牌出错");
        //    $user[GlobalBean::$token] = $token;
        //}
        $user = false;//这里直接返回session_key和openid
        return $user ? $user : $resultMap->getData();
    }
}
